/**
 *  Java Api For Ecco Generated Applications 
 *  
 *  Copyright (C) 2000  by PDTec GmbH 
 *
 *  @author  Michael Weirich
 */

package pdtec.ecco.meta;

/**
 * The class Application is a proxy for your ECCO generated application library.
 * It's the key class to access meta data, because it dynamically loads the ECCO
 * library when passing the library name to its constructor. After loading the   
 * library the native methods of this API are ready for usage.
 * @see  pdtec.ecco.inst.InstApplication
 */
public class Application {
    
    /**
     * The instance id of Application is controlled by the native method load and unload
     * in the underlying dll.
     * The maximum number of instances is limited to 16 and
     * cannot be customized for now.
     *
     * @see pdtec.ecco.meta.Application#getId()
     */
    private int id;

    /** Internal semaphore - prevents native methods being called from different
     *  threads at the same time.
     */
    private static ThreadLock lock= new ThreadLock();
    
    /** Represents the EXPRESS built in type STRING. */	
     public Type EccoString;
    /** Represents the EXPRESS built in type INTEGER. */
     public Type EccoInteger;
    /** Represents the EXPRESS built in type REAL. */
     public Type EccoReal;
    /** Represents the EXPRESS built in type NUMBER. */
     public Type EccoNumber;
    /** Represents the EXPRESS built in type BINARY. */
     public Type EccoBinary;
    /** Represents the EXPRESS built in type LOGICAL. */
     public Type EccoLogical;
    /** Represents the EXPRESS built in type BOOLEAN. */
     public Type EccoBoolean;
    
    /**
     * Protected standard constructor.
     */
    protected Application() {}
    
    /**
     * The constructor is called with the name of the ecco application to be loaded for meta data access. 
     * @param       libName the name of the ecco  dll to be loaded
     * @see       pdtec.ecco.inst.InstApplication#InstApplication( String libName )
     */
    public Application(String libName) throws EccoException {
	EccoInteger = null;
	EccoNumber = null;
	EccoReal = null;
	EccoString = null;
	EccoLogical = null;
	EccoBoolean = null;
	EccoBinary = null;	
	load( libName, false );
    } /* constructor */
    
    /**
     * The load method loads the specified ecco application and sets the id of the Application
     * to a value greater than zero.
     * Two loading modes are supplied:
     * The dll may be used to serve either for an Application instance or an InstApplication instance.
     * The load method is called from the constructor methods of Application and InstApplication classes. 
     *
     * @param     libName  the name of the desired library to be loaded.
     * @param     isInstApplication  boolean variable which determines dll initialization.
     * @exception EccoException in case an error occurs
     */
    protected native synchronized void load( String libName , boolean isInstApplication ) throws EccoException;
    
    /**
     * The unload method unloads the ecco application and resets the Application id to -1. 
     * @exception EccoException in case an error occurs
     */
    protected native synchronized void unload() throws EccoException;
    
    /** This method initializes the standard type variables.
     * @exception EccoException in case an error occurs
     */
    public void setStandardTypes() throws EccoException {
	EccoString  = Type.getByName(id,"","STRING");
	EccoInteger = Type.getByName(id,"","INTEGER");
	EccoReal    = Type.getByName(id,"","REAL");
	EccoNumber  = Type.getByName(id,"","NUMBER");
	EccoBinary  = Type.getByName(id,"","BINARY");
	EccoLogical = Type.getByName(id,"","LOGICAL");
	EccoBoolean = Type.getByName(id,"","BOOLEAN");
    } // setStandardTypes
    
    /**
     * The function returns the internal id.
     * The instance id of Application is controlled by the native methods load() and unload().
     * @return the current id value, should be a non-negative integer
     */
    public int getId() {
	return(id);
    } /* getId */
    
    /** Returns the name of the application. 
     * @exception EccoException in case an error occurs
     */
    public native synchronized String getName() throws EccoException;
    
    /**
     * Returns all available schemas defined by the underlying  ecco application.
     * @return array of schemas or empty array
     * @exception EccoException in case an error occurs
     */
    public native synchronized Schema[] getSchemas() throws EccoException;
    
    /** The static initializer loads the implementation of the native methods. The native methods are usually located in
     * in library eccojava2.dll. */
    static {
	System.loadLibrary("eccojava2");
    } // static initializer
    
    /** The finalize method unloads the loaded ecco application. */
    protected void finalize() {
	try {
	    if( id != -1 )
		unload();
	} catch ( EccoException except ) {
	    System.out.println(except.getMessage() );
	} // catch
	
    } /* finalize */
    
} // class Application

/**
 *  For each application an object of class ThreadLock is created. It is used to protect native methods 
 *  being called by more than one thread at once. 
 *  @see Application#lock
 */
class ThreadLock {};







